﻿/**
 * Copyright © TnT-VNGroup 2011
 * PROJECT:   SmartCollector
 * $HeadURL: http://smartcollector.googlecode.com/svn/branches/Srcs/SmartCollector.HtmlParser/DataManager/SiteItemStructure.cs $
 * $Author: chithanh12@gmail.com $
 * $Date: 2011-04-20 18:46:52 +0000 (Wed, 20 Apr 2011) $
 * $Rev: 94 $
 **/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.ComponentModel;

namespace HtmlParser.SiteManager
{
    public class SiteItemStructure
    {
        #region Members
        [XmlAttribute]
        public int SiteId
        {
            get;
            set;
        }

        [XmlAttribute]
        public string SiteDomainName
        {
            get;
            set;
        }

        [XmlIgnore]
        [DefaultValue(false)]
        public bool IsDirty
        {
            get;
            set;
        }
        
        public Dictionary<RegionArea, TagSelector> ConstraintCollections
        {
            get
            {
                return m_siteConstraint;
            }
            set
            {
                m_siteConstraint = value;
            }
        }

        private Dictionary<RegionArea, TagSelector> m_siteConstraint = new Dictionary<RegionArea, TagSelector>();
        #endregion

        /// <summary>
        /// Adds the constraint.
        /// </summary>
        /// <param name="area">The area.</param>
        /// <param name="selector">The selector.</param>
        public void AddConstraint(RegionArea area,TagSelector selector)
        {
            if (!m_siteConstraint.ContainsKey(area))
            {
                m_siteConstraint.Add(area, selector);
            }
            else
            {
                m_siteConstraint[area] = selector;
            }
            IsDirty = true;
        }

        /// <summary>
        /// Adds the constraint.
        /// </summary>
        /// <param name="area">The area.</param>
        /// <param name="attributeName">Name of the attribute.</param>
        /// <param name="attributeValue">The attribute value.</param>
        public void AddConstraint(RegionArea area, string attributeName, string attributeValue)
        {
            TagSelector selector = null;
            if (m_siteConstraint.ContainsKey(area))
            {
                selector = m_siteConstraint[area];
            }
            else
            {
                selector = new TagSelector();
                m_siteConstraint.Add(area, selector);
            }
            if (selector != null)
            {
                selector.AddConstraint(attributeName, attributeValue);
            }
            IsDirty = true;
        }

        /// <summary>
        /// Gets the constraint.
        /// </summary>
        /// <param name="area">The area.</param>
        /// <returns></returns>
        public TagSelector GetConstraint(RegionArea area)
        {
            if (m_siteConstraint.ContainsKey(area))
            {
                return m_siteConstraint[area];
            }
            return null;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class TagSelector
    {
        #region Members
        private Dictionary<string, string> m_constraintCollection = new Dictionary<string, string>();
        #endregion

        #region Properties
        /// <summary>
        /// Gets the constraint collections.
        /// </summary>
        [XmlAttribute]
        public Dictionary<string, string> ConstraintCollections
        {
            get
            {
                return m_constraintCollection;
            }
            set
            {
                m_constraintCollection = value;
            }
        }
        #endregion

        #region Methods

        /// <summary>
        /// Adds the constraint.
        /// </summary>
        /// <param name="keyName">Name of the key.</param>
        /// <param name="value">The value.</param>
        public void AddConstraint(string keyName, string value)
        {
            /// BKM: Important
            if (!m_constraintCollection.ContainsKey(keyName))
            {
                m_constraintCollection.Add(keyName, value);
            }
            else
            {
                m_constraintCollection[keyName] = value;
            }
        }

        /// <summary>
        /// Checks the is this tag.
        /// </summary>
        /// <param name="tag">The tag.</param>
        /// <returns></returns>
        public bool CheckIsThisTag(HtmlTag tag)
        {
            if (tag == null)
            {
                return false;
            }
            bool isContain = true;
            foreach (KeyValuePair<string, string> constraint in m_constraintCollection)
            {
                isContain &= tag.Attributes
                    .Where(p => p.Name.ToLower() == constraint.Key.ToLower() 
                            && p.Value.ToLower() == constraint.Value.ToLower())
                    .Count() > 0;
            }
            return isContain;
        }


        #endregion
    }

    /// <summary>
    /// 
    /// </summary>
    public enum RegionArea
    {
        Boundary,
        Title,
        Description,
        Content,
        Author,
        Source,
        NearestBoundary
    }

    public enum AttributeKey
    {
        Class,
        Id,
        Other
    }

    #region Comment Serialize Dictionary

    //[XmlRoot("dictionary")]
    //public class SerializableDictionary<TKey, TValue>
    //    : Dictionary<TKey, TValue>, IXmlSerializable
    //{
    //    #region IXmlSerializable Members
    //    public System.Xml.Schema.XmlSchema GetSchema()
    //    {
    //        return null;
    //    }

    //    public void ReadXml(System.Xml.XmlReader reader)
    //    {
    //        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
    //        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
    //        bool wasEmpty = reader.IsEmptyElement;
    //        reader.Read();
    //        if (wasEmpty)
    //        {
    //            return;
    //        }
    //        while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
    //        {
    //            reader.ReadStartElement("item");
    //            reader.ReadStartElement("key");
    //            TKey key = (TKey)keySerializer.Deserialize(reader);
    //            reader.ReadEndElement();
    //            reader.ReadStartElement("value");
    //            TValue value = (TValue)valueSerializer.Deserialize(reader);
    //            reader.ReadEndElement();
    //            this.Add(key, value);
    //            reader.ReadEndElement();
    //            reader.MoveToContent();
    //        }
    //        reader.ReadEndElement();
    //    }

    //    public void WriteXml(System.Xml.XmlWriter writer)
    //    {
    //        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
    //        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
    //        foreach (TKey key in this.Keys)
    //        {
    //            writer.WriteStartElement("item");
    //            writer.WriteStartElement("key");
    //            keySerializer.Serialize(writer, key);
    //            writer.WriteEndElement();
    //            writer.WriteStartElement("value");
    //            TValue value = this[key];
    //            valueSerializer.Serialize(writer, value);
    //            writer.WriteEndElement();
    //            writer.WriteEndElement();
    //        }
    //    }
    //    #endregion
    //}
    #endregion
}
